The question that led here: can a maze's wall structure encode an image, so that the passages flow along edges and the topology respects the picture's visual structure?
Gradient Fields
The input image gets processed with Scharr gradient filters, sharper than Sobel, producing two fields: an angle field (dominant edge direction at each point) and a contrast field (edge strength). Each maze cell gets assigned an orientation by computing a circular median of the gradient angles within its footprint, and walls are placed orthogonal to that orientation: if the gradient says "the edge runs left-to-right here," the wall goes top-to-bottom, creating a passage that follows the edge. Cells in contrast bin 0 (no significant edges) become open cells with no walls, creating clearings where the image has flat regions.
pipeline:
1. input image → Scharr gradients → angle field + contrast field
2. per-cell circular median orientation
3. Floyd-Steinberg dithering (orientation + contrast)
4. wall placement orthogonal to chosen axis
5. contrast bin 0 → open cell (no walls)
6. SVG output

Angular Statistics and Error Diffusion
Circular median, not circular mean, because angles wrap around. You can't average 350° and 10° with an arithmetic mean and expect 0°; the circular median handles the wraparound correctly, at significant computational cost compared to a standard median (there's no closed-form shortcut for circular data).
Floyd-Steinberg dithering shows up twice in this pipeline, which is unusual since it's normally an image processing technique. The first pass quantizes the continuous orientation field into discrete wall directions; the second pass thresholds the contrast field into density levels. In both cases the error diffusion distributes quantization error to neighboring cells, preventing the harsh banding that simple rounding would produce, and the result is a spatially coherent distribution of wall angles and densities that reads as organic texture rather than blocky regions. Applying an image-processing algorithm to an orientation field was a speculative choice, but the error diffusion property is what matters, not the pixel domain it was designed for.
Spanning Trees and Parameters
The generator supports square grids (4-neighbor connectivity) and triangle grids (6-neighbor, which produces more organic-looking mazes because each cell has six possible wall orientations instead of four). For the spanning tree, Prim's and Kruskal's are both available, with edge weights influenced by a contour distance field using Gaussian falloff: w_d = exp(-(dist/r)²). The tangent field t ∝ (-dy, dx) defines flow direction, and the combined weight W(e) = α·w_d·alignment + (1-α)·base lets the α parameter control how strongly the image guides the maze versus how much randomness remains.
Loopiness adds extra edges beyond the spanning tree (creating cycles and alternative paths), branchiness controls the preference for long corridors versus many short branches, and dead-end rate determines how many passages terminate. These interact with the image-guided weights in non-obvious ways: high loopiness near strong contours creates channel-like structures that emphasize edges, while low branchiness with strong guidance produces long flowing passages that trace contours like rivers.
Output is SVG, so the mazes scale to any print size. I've printed some at poster scale and the detail holds up. The image structure gives you subtle visual hints about the path layout: you're solving the maze and reading the picture simultaneously.
